﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ChoMy.Payment
{
    // Các tham số tĩnh: Tài khoản OnePAY, thông số cổng thanh toán
    public class OnePaySystem
    {
        // Version module cổng thanh toán, cố định và mặc định là “2”
        public string Version { get; set; }

        // Chức năng thanh toán, giá trị của đối số này cố định và mặc định là “pay”
        public string Command { get; set; }

        // Ngôn ngữ hiển thị trên website. Giá trị có thể là “en” hoặc “vn”
        public string Locale { get; set; }

        // Địa chỉ trỏ vào file DR để nhận kết quả trả về
        public string ReturnUrl { get; set; }

        // Loại tiền thanh toán, mặc định là VND
        public string Currency { get; set; }

        // ===========================================================================
        // Cặp tài khoản của mỗi đơn vị do Onepay cấp
        public string VirtualPaymentClientURL { get; set; }
        public string AccessCode { get; set; }
        public string Merchant { get; set; }
        public string SecureHash { get; set; }

        public OnePaySystem()
        {
            Version = "2";
            Command = "pay";
            Locale = "vn";
        }
    }

    // Các tham số web site gán giá trị động: Price, Order ID,...
    public class OnePayRedirect
    {
        // Mã giao dịch, biến số này yêu cầu là duy nhất mỗi lần gửi sang OnePay
        public string MerchTxnRef { get; set; }

        // Thông tin đơn hàng thường mã đơn hàng hoặc mô tả ngăn gon về đơn hàng
        public string OrderInfo { get; set; }

        // Khoản tiền thanh toán, giá trị chuyền vào không có dấu
        // Cổng thanh toán lấy hai ký tự cuối cùng là phần thập phân, nhân với 100 trước khi chuyển sang cổng thanh toán
        public string Amount { get; set; }

        // Địa chỉ IP khách hàng thực hiện thanh toán – Không được đặt cố định 1 IP
        public string TicketNo { get; set; }

        // Link trang thanh toán của website trước khi chuyển sang Onepay
        public string AgainLink { get; set; }

        // Tiêu đề cổng thanh toán trên trình duyệt
        public string Title { get; set; }
    }

    public class OnePayResponse
    {
        // Mã giao dịch được sinh ra bởi cổng thanh toán để chỉ trạng thái giao dịch.
        // Giá trị là “0” (zero) cho biết giao dịch đã xử lý thành công. 
        // Tất cả các giá trị khác là giao dịch thất bại.
        public string TxnResponseCode { get; set; }

        // Giá trị của đối số vpc_Amount trên file DO được trả lại trên file DR
        public string Amount { get; set; }

        // Ngôn ngữ hiển thị khi thanh toán: en- Tiếng Anh, vn- Tiếng Việt
        public string Localed { get; set; }

        // Giá trị của vpc_Command đã gửi đi trong file DO được trả lại trên file DR
        public string Command { get; set; }

        // Một mã được sinh ra từ cổng thanh toán cho biết loại thẻ đã sử dụng trong giao dịch
        public string Card { get; set; }

        // Giá trị của đối số vpc_OrderInfo trên file DO được trả lại trên file DR
        public string OrderInfo { get; set; }

        // Giá trị của đối số vpc_Merchant gửi đi từ file DO được trả lại trong file DR
        public string MerchantID { get; set; }

        // Một mã code được sinh ra từ ngân hàng để chấp nhận hoặc từ chối giao dịch. 
        // Nó là một tùy chọn và có thể không được áp dụng với tất cả các ngân hàng.
        public string AuthorizeID { get; set; }

        // Giá trị của đối số vpc_MerchTxnRef gửi đi từ file DO trả lại trên file DR
        public string MerchTxnRef { get; set; }

        // Một số duy nhất được sinh ra từ cổng thanh toán trên giao dịch. 
        // Nó được lưu trên cổng thanh toán như ánh xạ cho phép người sử dụng thực hiện các chức năng như refund hay capture.
        public string TransactionNo { get; set; }

        // Mã trả về từ ngân hàng thanh toán
        public string AcqResponseCode { get; set; }

        // Chỉ ra lỗi giao dịch có thể có khi thanh toán
        public string Message { get; set; }

        public string DrExists { get; set; }

        public string HashValidateResult { get; set; }
        public string Version { get; set; }
    }

    public class OnePayHandling
    {
        public string Redirect(OnePayRedirect model, bool inland, string returnUrl)
        {
            OnePaySystem op = new OnePaySystem();
            op.ReturnUrl = returnUrl;

            if (inland == true) // Nội địa
            {
                //op.VirtualPaymentClientURL = "https://onepay.vn/onecomm-pay/vpc.op"; // Hệ thống thật
                op.VirtualPaymentClientURL = "http://mtf.onepay.vn/onecomm-pay/vpc.op"; // Hệ thống test
                op.AccessCode = "D67342C2";
                op.Merchant = "ONEPAY";
                op.SecureHash = "A3EFDFABA8653DF2342E8DAC29B51AF0";
                op.Currency = "VND";
            }
            else // Quốc tế
            {
                //op.VirtualPaymentClientURL = "https://onepay.vn/vpcpay/vpcpay.op";  // Hệ thống thật
                op.VirtualPaymentClientURL = "http://mtf.onepay.vn/vpcpay/vpcpay.op";  // Hệ thống test
                op.AccessCode = "6BEB2546";
                op.Merchant = "TESTONEPAY";
                op.SecureHash = "6D0870CDE5F24F34F3915FB0045120DB";
            }

            VPCRequest conn = new VPCRequest(op.VirtualPaymentClientURL);
            conn.SetSecureSecret(op.SecureHash);

            conn.AddDigitalOrderField("vpc_Locale", op.Locale);
            conn.AddDigitalOrderField("vpc_Version", op.Version);
            conn.AddDigitalOrderField("vpc_Command", op.Command);
            conn.AddDigitalOrderField("vpc_Merchant", op.Merchant);
            conn.AddDigitalOrderField("vpc_AccessCode", op.AccessCode);
            conn.AddDigitalOrderField("vpc_Currency", op.Currency);
            conn.AddDigitalOrderField("vpc_ReturnURL", op.ReturnUrl);

            conn.AddDigitalOrderField("vpc_Amount", model.Amount);
            conn.AddDigitalOrderField("vpc_OrderInfo", model.OrderInfo);
            conn.AddDigitalOrderField("vpc_TicketNo", model.TicketNo);
            conn.AddDigitalOrderField("vpc_MerchTxnRef", model.MerchTxnRef);
            conn.AddDigitalOrderField("AgainLink", model.AgainLink);
            conn.AddDigitalOrderField("Title", model.Title);

            string url = conn.Create3PartyQueryString();
            return url;
        }

        public OnePayResponse Response(bool inland, System.Collections.Specialized.NameValueCollection queryString)
        {
            OnePaySystem ops = new OnePaySystem();

            if (inland == true)
            {
                ops.VirtualPaymentClientURL = "http://mtf.onepay.vn/onecomm-pay/vpc.op";
                ops.SecureHash = "A3EFDFABA8653DF2342E8DAC29B51AF0";
            }
            else
            {
                ops.VirtualPaymentClientURL = "http://mtf.onepay.vn/vpcpay/vpcpay.op";
                ops.SecureHash = "6D0870CDE5F24F34F3915FB0045120DB";
            }

            VPCRequest conn = new VPCRequest(ops.VirtualPaymentClientURL);
            conn.SetSecureSecret(ops.SecureHash);

            OnePayResponse opr = new OnePayResponse();
            opr.HashValidateResult = conn.Process3PartyResponse(queryString);
            opr.TxnResponseCode = conn.GetResultField("vpc_TxnResponseCode");
            opr.Amount = conn.GetResultField("vpc_Amount");
            opr.Localed = conn.GetResultField("vpc_Locale");
            opr.Command = conn.GetResultField("vpc_Command");
            opr.Version = conn.GetResultField("vpc_Version");
            opr.Card = conn.GetResultField("vpc_Card");
            opr.OrderInfo = conn.GetResultField("vpc_OrderInfo");
            opr.MerchantID = conn.GetResultField("vpc_Merchant");
            opr.AuthorizeID = conn.GetResultField("vpc_AuthorizeId");
            opr.MerchTxnRef = conn.GetResultField("vpc_MerchTxnRef");
            opr.TransactionNo = conn.GetResultField("vpc_TransactionNo");
            opr.AcqResponseCode = conn.GetResultField("vpc_AcqResponseCode");
            opr.Message = conn.GetResultField("vpc_Message");

            return opr;
        }

        public string OnePayErrorMessage(string code)
        {
            switch (code)
            {
                case "1": return "Ngân hàng phát hành thẻ không cấp phép. Vui lòng liên hệ ngân hàng.";
                case "2": return "Ngân hàng phát hành thẻ không cấp phép. Vui lòng liên hệ ngân hàng.";
                case "3": return "Cổng thanh toán không nhận được kết quả trả về từ ngân hàng phát hành thẻ.";
                case "4": return "Thẻ hết hạn sử dụng.";
                case "5": return "Thẻ không đủ hạn mức hoặc tài khoản không đủ số dư thanh toán.";
                case "6": return "Lỗi từ ngân hàng phát hành thẻ.";
                case "7": return "Lỗi phát sinh trong quá trình xử lý giao dịch.";
                case "8": return "Ngân hàng phát hành thẻ không hỗ trợ giao dịch Internet.";
                case "9": return "Ngân hàng phát hành thẻ từ chối giao dịch.";
                case "B/W": return "Không xác thực được 3D-Secure. Liên hệ ngân hàng phát hành để được hỗ trợ.";
                case "E": return "Bạn nhập sai CSC hoặc thẻ vượt quá hạn mức lần thanh toán.";
                default: return "Bạn vui lòng thử lại lần nữa.";
            }
        }
    }
}
